<?php
declare(strict_types=1);

namespace App\Service;

use App\Model\Dao\RiskRuleWhitetextConnDao;
use App\Model\Dao\RiskRuleWhitetextParamDao;
use App\Utils\CustomUtils;
use App\Utils\StringUtils;
use Hyperf\Database\Query\Builder;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use App\Model\Dao\RiskRuleWhitetextDao;
use App\Exception\XZXValidationException;
use App\Constants\XZXResponseCode;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Arr;
use Hyperf\Utils\Coroutine;
use App\Utils\DateUtils;
use parallel\Sync;


class RiskRuleWhitetextService {

    /**
     * @Inject()
     * @var RiskRuleWhitetextDao
     */
    private $RiskRuleWhitetextDao;

    /**
     * @Inject()
     * @var RiskRuleWhitetextConnDao
     */
    private $RiskRuleWhitetextConnDao;

    /**
     * @Inject()
     * @var RiskRuleWhitetextParamDao
     */
    private $RiskRuleWhitetextParamDao;

    /**
     * @Inject()
     * @var SyncService
     */
    private $SyncService;

    /**
     * 列表
     *
     * @param array $param
     *
     * @return array
     */
    public function list (array $param) {

        $limit = $param['limit'];
        $page  = $param['page'];

        $total = $this->RiskRuleWhitetextDao->getCount($param);
        $list  = $this->RiskRuleWhitetextDao->getList($param, $page, $limit);

        $list = CustomUtils::formatCreateTime($list);
        foreach ($list as $k => $v) {
            // $v['createTime'] = xeGetDateTime($v['createTime']);
            $v['strStatus'] = $this->RiskRuleWhitetextDao->strStatus($v['status']);
            $list[$k] = $v;
        }
        $data = [
            'total' => $total,
            'list'  => $list,
        ];

        return CustomUtils::buildSuccess($data);
    }

    /**
     * 列表
     *
     * @param array $params
     *
     * @return array
     */
    public function options (array $params) {

        $list  = $this->RiskRuleWhitetextDao->getWhereList(function (Builder $query) use ($params) {
            $query->where('status', 1);

            !empty($params['search']) && $query->where('whiteTextName', 'like', "%{$params['search']}%");
        });

        $list = array_map(function ($item) {
            return [
                'label' => $item['whiteTextName'],
                'value' => $item['id'],
            ];
        }, $list);

        $data = $list;

        return CustomUtils::buildSuccess($data);
    }

    /**
     * 详情
     *
     * @param $param
     *
     * @return array
     */
    public function get ($param) {

        $info = $this->RiskRuleWhitetextDao->get($param['id']);

        if (!$info) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        // 关联数据
        $conn = $this->RiskRuleWhitetextConnDao->getWhereList([
            'whiteTextId' => $info['id'],
            'status'      => 1,
        ]);
        $conn = array_column($conn, 'paramId');
        if (empty($conn)) {
            $paramList = [];
        }
        else {
            $paramList = $this->RiskRuleWhitetextParamDao->getWhereList(function (Builder $query) use ($conn) {
                $query->where('status', 1);
                $query->whereIn('id', $conn);
            });
        }

        $info['paramList'] = $paramList;

        $data = $info;

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 从参数过滤得到添加/更新数组
     *
     * @param $param
     *
     * @return array
     */
    protected function _filterUpdate ($param) {

        $update = Arr::only($param, [
            'whiteTextName',
            'status',
        ]);

        return $update;
    }

    /**
     * 设置参数关联
     *
     * @param $param
     */
    protected function _setConn ($id, $param) {

        $conn = Arr::pull($param, 'conn', []);

        // 查询有效的
        if (!empty($conn)) {
            $list = $this->RiskRuleWhitetextParamDao->getWhereList(function (Builder $query) use ($conn) {
                $query->whereIn('id', $conn);
            });
            $conn = array_column($list, 'id');
        }

        Db::beginTransaction();

        try {

            // 全删
            $this->RiskRuleWhitetextConnDao->delWhere(['whiteTextId' => $id]);

            // 全增
            $update = Arr::only($param, ["createBy", "updateBy"]);
            $update['whiteTextId'] = $id;

            $updateList = [];
            foreach ($conn as $paramId) {
                array_push($updateList, array_merge($update, [
                    'paramId' => $paramId,
                    'id' => StringUtils::uuidV4()
                ]));
            }

            $this->RiskRuleWhitetextConnDao->add($updateList);

        } catch (\Exception $err) {
            Db::rollBack();
            throw $err;
        }

        Db::commit();

    }

    /**
     * 添加
     *
     * @param $param
     *
     * @return array
     * @throws \Throwable
     */
    public function add ($param) {

        $id = StringUtils::uuidV4();

        $update = $this->_filterUpdate($param);
        $update = array_merge($update, Arr::only($param, ['createBy', 'updateBy']));

        $update['id'] = $id;

        Db::beginTransaction();

        try {

            $this->RiskRuleWhitetextDao->insert($update);

            $this->_setConn($id, $param);

        } catch (\Exception $err) {
            Db::rollBack();
            throw $err;
        }

        Db::commit();

        $data = ['id' => $update['id']];

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 编辑
     *
     * @param $param
     *
     * @return array
     */
    public function edit ($param) {

        $id = Arr::pull($param, 'id');

        $info = $this->RiskRuleWhitetextDao->get($id);
        if (!$info) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        $update = $this->_filterUpdate($param);
        $update = array_merge($update, Arr::only($param, ['updateBy']));

        Db::beginTransaction();

        try {

            $this->RiskRuleWhitetextDao->update($id, $update);

            $this->_setConn($id, $param);

            // 更新缓存
            ApplicationContext::getContainer()->get(SyncService::class)->syncWhiteText($id);

        } catch (\Exception $err) {
            Db::rollBack();
            throw $err;
        }

        Db::commit();

        $this->SyncService->syncWhiteText($id);

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), CustomUtils::xzxEmptyObject());
    }

    /**
     * 删除
     *
     * @param $param
     *
     * @return array
     */
    public function del ($param) {

        $id = Arr::pull($param, 'id');

        $result = $this->RiskRuleWhitetextDao->get($id);

        if (!$result) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        Db::beginTransaction();

        try {

            $this->RiskRuleWhitetextDao->del($id);

            $this->_setConn($id, []);

            // 更新缓存
            ApplicationContext::getContainer()->get(SyncService::class)->syncWhiteText($id);

        } catch (\Exception $err) {
            Db::rollBack();
            throw $err;
        }

        Db::commit();

        $this->SyncService->syncWhiteText($id);

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), CustomUtils::xzxEmptyObject());
    }

}
